﻿#region namespace

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;

#endregion

namespace Cherry.Agile.Cryptography
{
    /// <summary>
    /// 非对称加密
    /// </summary>
    public sealed class RSACryption
    {
        RSACryptoServiceProvider rsa;
        const int length = 1024;
        /// <summary>
        /// 构造函数
        /// </summary>
        public RSACryption()
        {
            rsa = new RSACryptoServiceProvider(length);
        }

        /// <summary>
        /// 创建密钥
        /// </summary>
        /// <param name="publicKey">公钥</param>
        /// <param name="privateKey">私钥</param>
        public static void CreateKey(out string publicKey,out string privateKey)
        {
            var rsa = new RSACryptoServiceProvider(2024);
            
            publicKey = rsa.ToXmlString(false);
            
            privateKey = rsa.ToXmlString(true);
        }

        /// <summary>
        /// 使用公钥加密数据
        /// </summary>
        /// <param name="data">待加密字符</param>
        /// <param name="publicKey">公钥</param>
        /// <returns></returns>
        public byte[] EncryptData(string data, string publicKey)
        {
            var vals = UTF8Encoding.Default.GetBytes(data);
            return EncryptData(vals ,publicKey);
        }

        /// <summary>
        /// 使用公钥加密数据
        /// </summary>
        /// <param name="data">待加密字节</param>
        /// <param name="publicKey">公钥</param>
        /// <returns></returns>
        public byte[] EncryptData(byte[] data,string publicKey)
        {
            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(2024);
            rsa.FromXmlString(publicKey);
            return rsa.Encrypt(data, false);
        }

        /// <summary>
        /// 使用私钥解密数据
        /// </summary>
        /// <param name="data">待解密字节</param>
        /// <param name="privateKey">私钥</param>
        /// <returns></returns>
        public byte[] DecryptData(byte[] data, string privateKey)
        {
           rsa.FromXmlString(privateKey);
           return rsa.Decrypt(data, false);
        }

        /// <summary>
        /// 签名数据
        /// </summary>
        /// <param name="data">待签名字节</param>
        /// <param name="privateKey">私钥</param>
        /// <returns></returns>
        public byte[] Sign(byte[] data, string privateKey)
        {
           rsa.FromXmlString(privateKey);
           return rsa.SignData(data, "MD5");
        }

        /// <summary>
        /// 验证加密的数据是否正确
        /// </summary>
        /// <param name="data">私钥加密之后的数据</param>
        /// <param name="Signature">签名之后的数据</param>
        /// <param name="publicKey">公钥</param>
        /// <returns></returns>
        public bool Verify(byte[] data, byte[] Signature,string publicKey)
        {
            rsa.FromXmlString(publicKey);
            return rsa.VerifyData(data, "MD5", Signature);
        }
    }
}
